package com.ndhutu.ee.util.ali.oss;

import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.*;
import com.ndhutu.ee.util.DateUtil;
import com.ndhutu.ee.util.StringUtil;

import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.*;

/**
 * 阿里oss存储工具类
 * @Author Shane
 * @Date 2019/9/211:10
 * @param
 * @return
 **/
public class OSSUtil {

    /**
     * 使用STS凭证获取url签名
     * @Author Shane
     * @Date 2019/9/1218:36
     * @param
     * @return
     **/
    public static Map<String, Object> getSignature(OSSConfig config, Integer userId, String objectName, String securityToken) throws Exception{
        //用户拿到STS临时凭证后，通过其中的安全令牌（SecurityToken）和临时访问密钥（AccessKeyId和AccessKeySecret）生成OSSClient。
        OSS ossClient = new OSSClientBuilder().build(config.getEndpoint(), securityToken, config.getAccessKeyId(), config.getAccessKeySecret());

        GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(config.getBucketName(), objectName, HttpMethod.PUT);

        // 设置URL过期时间为10分钟。
        Date expiration = new Date(System.currentTimeMillis() + 10 * 60 * 1000);
        request.setExpiration(expiration);
        // 设置ContentType。
//        request.setContentType(DEFAULT_OBJECT_CONTENT_TYPE);
        // 设置自定义元信息。
        request.addUserMetadata("author", userId+"");

        URL signedUrl = ossClient.generatePresignedUrl(request);

        return null;
    }

    /**
     * 获取上传签名
     * @Author Shane
     * @Date 2019/9/15 17:41
     * @param 
     * @return 
     */
    public static Map<String, String> getSignature(OSSConfig config) throws Exception{
        OSS client = new OSSClientBuilder().build(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret());

        //设置URL过期时间为10分钟。
        Date expiration = new Date(System.currentTimeMillis() + 10 * 60 * 1000);
        //设置上传路径
        String dir = StringUtil.getRandomUploadPath();
        PolicyConditions policyConds = new PolicyConditions();
        //设置上传文件大小
        policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
        //设置上传文件位置
        policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
        //上传路径
        String host = "https://" + config.getBucketName() + "." + config.getEndpoint();

        String postPolicy = client.generatePostPolicy(expiration, policyConds);
        byte[] binaryData = postPolicy.getBytes("utf-8");
        String encodedPolicy = BinaryUtil.toBase64String(binaryData);
        String postSignature = client.calculatePostSignature(postPolicy);

        Map<String, String> respMap = new LinkedHashMap<String, String>();
        respMap.put("accessKeyId", config.getAccessKeyId());
        respMap.put("policy", encodedPolicy);
        respMap.put("signature", postSignature);
        respMap.put("dir", dir);
        respMap.put("host", host);
        respMap.put("expire", String.valueOf(expiration.getTime() / 1000));

        return respMap;
    }

    /**
     * 上传
     * @Author Shane
     * @Date 2020/2/25 23:22
     * @param file  包含http则为网络流，否则怎为文件流
     * @return
     */
    public static String uploadFile(OSSConfig config, String file) throws Exception {
        //保存位置
        String suffix = file.substring(file.lastIndexOf("."));
        String savePath = DateUtil.getCurrTimeStr("yyyy")+"/"+DateUtil.getCurrTimeStr("MM")+"/"+DateUtil.getCurrTimeStr("dd")+"/"+DateUtil.getCurrTimeStr("HHmmss")+suffix;

        uploadFile(config, file, savePath);

        return savePath;
    }

    public static void uploadFile(OSSConfig config, String file, String savePath) throws Exception{
        uploadFile(config, file, savePath, null);
    }

    public static void uploadFile(OSSConfig config, String file, String savePath, Callback callback) throws Exception{
        OSS oss = new OSSClientBuilder().build(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret());

        InputStream is = null;
        if(file.indexOf("http") > -1){
            //上传网络流
            is = new URL(file).openStream();
        }else{
            //上传文件流
            is = new FileInputStream(file);
        }

        PutObjectRequest request = new PutObjectRequest(config.getBucketName(), savePath, is);
        if(callback != null){
            request.setCallback(callback);
        }

        PutObjectResult result = oss.putObject(request);

        /*if(callback != null){
            // 读取上传回调返回的消息内容。
            byte[] buffer = new byte[1024];
            result.getResponse().getContent().read(buffer);
            // 数据读取完成后，获取的流必须关闭，否则会造成连接泄漏，导致请求无连接可用，程序无法正常工作。
            result.getResponse().getContent().close();
        }*/

        oss.shutdown();
    }

    /**
     * 批量删除文件
     * @Author AppiJ
     * @Date 2021/3/10 10:55
     * @param
     * @return
     */
    public static void deleteFile(OSSConfig config, List<String> files){
        // 创建OSSClient实例
        OSS ossClient = new OSSClientBuilder().build(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret());
        ossClient.deleteObjects(new DeleteObjectsRequest(config.getBucketName()).withKeys(files));

        // 关闭OSSClient
        ossClient.shutdown();
    }
}
